package com.zx.jhpt.login;

import com.zx.framework.core.pagination.Pagination;

import com.zx.framework.core.util.BeanUtil;
import com.zx.framework.core.util.DatetimeUtils;
import com.zx.framework.core.util.StringUtil;
import com.zx.framework.plat.dept.po.Dept;
import com.zx.framework.plat.dept.service.DeptService;
import com.zx.framework.plat.login.LoginAdapterController;
import com.zx.framework.plat.user.po.User;
import com.zx.framework.plat.user.service.UserService;
import com.zx.framework.plat.user.vo.UserVo;
import com.zx.framework.web.exception.AjaxException;
import com.zx.framework.web.exception.UIException;
import com.zx.jhpt.excel.Engine;
import com.zx.jhpt.excel.vo.Column;
import com.zx.jhpt.excel.vo.Risk;
import com.zx.jhpt.po.Fxfkjz;
import com.zx.jhpt.po.Enclosure;
import com.zx.jhpt.po.Replymessage;
import com.zx.jhpt.service.EnclosureService;
import com.zx.jhpt.service.EngineService;
import com.zx.jhpt.service.ReplyMessageService;
import com.zx.jhpt.service.FxfkjzService;
import com.zx.jhpt.util.ExcelUtil;
import com.zx.jhpt.vo.JhptConts;
import com.zx.jhpt.vo.ReplymessageVo;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/repm")
public class ReplMessageController extends LoginAdapterController {

	private static final Logger LOGGER = Logger.getLogger(ReplMessageController.class);

	@Resource
	private ReplyMessageService replyMessageService;
    @Resource
    private UserService userService;
    @Resource
    private DeptService deptService;
    @Resource
    private EngineService engineService;
    @Resource
    private EnclosureService enclosureService;
    @Resource
    private FxfkjzService fxfkjzService;
   

    @InitBinder("reply")
    public void replyBinder(WebDataBinder binder) throws Exception {
        binder.setFieldDefaultPrefix("reply.");
    }

    
	/**
	 * 回复信息页面
	 * @return
	 */
	@RequestMapping("/save")
	@ResponseBody
	public Map<String, Object> save(ReplymessageVo example){
		UserVo loginUser = getLoginUser();
		try {
//			if (StringUtil.isEmpty(example.getGdwfzr())) {
//				return clientMap().failure().message("单位负责人不可为空！").getMap();
//			}
//			if (StringUtil.isEmpty(example.getGdwzgld())) {
//				return clientMap().failure().message("单位主管不可为空！").getMap();
//			}
			if (StringUtil.isEmpty(example.getSftghzd())) {
				example.setSftghzd(JhptConts.REPLYMESSAGE_SFTGHZD_FALSE);
			}
			if (StringUtil.isEmpty(example.getGdwfkjg())) {
				return clientMap().failure().message("单位反馈结果不可为空！").getMap();
			}
			if (null == example.getYjzgwcsj()) {
				return clientMap().failure().message("预计整改完成时间不可为空").getMap();
			}
			if (StringUtil.isNotEmpty(example.getQtbz()) && StringUtil.length(example.getQtbz()) > 100) {
				return clientMap().failure().message("其他备注不得大于100个字符！").getMap();
			}
			Date date = new Date();
			Replymessage replymessage = new Replymessage();
			BeanUtil.copyProperties(example, replymessage);
			replymessage.setDeptid(loginUser.getDept().getId());
			replymessage.setDeptname(loginUser.getDept().getName());
			replymessage.setFksj(date);
			replymessage.setStatus(JhptConts.RM_STATUS_FIN);
			
			replyMessageService.update(replymessage);//程序先update后才有id,fxid
			
			return clientMap().success().message("保存成功！").getMap();
		} catch (Exception e) {
			LOGGER.error("反馈信息保存失败：", e);
			return clientMap().failure().message(e.getMessage()).getMap();
		}
	}

    
    
    /**
     * 查询回复
     * 历史风险
     * @return 回复信息的分页对象
     */
    @RequestMapping("/page")
    @ResponseBody
    public Pagination<Replymessage> page(@ModelAttribute("reply") Replymessage reply, Integer page, Integer rows){
        UserVo loginUser = getLoginUser();
        page = page==null?1:page;
        rows = rows==null?10:rows;
//        List<Dept> userDepts = deptService.findUserDepts(loginUser.getId());
//        Dept dept;
//        if (null != userDepts && !userDepts.isEmpty()){
//            dept = userDepts.get(0);
//            reply.setDeptid(dept.getId());
//        }else{
//            throw new AjaxException("用户部门异常,请联系管理员处理!");
//        }
        Pagination<Replymessage> replymessagePagination = replyMessageService.page(reply,loginUser,page,rows);
        for(Object object : replymessagePagination.getDatas()){
        	
            // 注释一下吧,这里用了个小魔法,hibernate直接查询了个复合对象,出来的实际内容是
            // Pagination<[Replymessage,Fxfkjz]>,JAVA本身不支持复合泛型,所以用实际对象强转
            Replymessage replymessage = (Replymessage)(((Object[])object)[0]);
            if(JhptConts.REPLYMESSAGE_SFTGHZD_TRUE.equals(replymessage.getSftghzd())){
            	//查询出风险点对应的回执单
                List<Enclosure> enclosures = enclosureService.getEnclByPkid(replymessage.getId());
                replymessage.setEnclosures(enclosures);
            }
        }
        return replymessagePagination;
    }
    
    
    @RequestMapping("/find")
    @ResponseBody
    public Object find(String replyId){
        User loginUser = getLoginUser();
        List<Dept> userDepts = deptService.findUserDepts(loginUser.getId());
        Dept dept;
        if (null != userDepts && !userDepts.isEmpty()){
            dept = userDepts.get(0);
        }else{
            throw new AjaxException("用户部门异常,请联系管理员处理!");
        }
        return replyMessageService.find(replyId,dept.getId());
    }

    /**
     * 获取风险详情
     * @param fxid 风险ID
     * @param cycle 风险周期
     * @param page 页码
     * @param rows 每页数据条数
     * @return 数据
     */
    @RequestMapping("detail_risk")
    @ResponseBody
    public Object detailRisk(
            String fxid,
            String cycle,
            Integer page,
            Integer rows
    ){
    	User user = getLoginUser();
        Risk risk = Engine.getRisk(fxid);
        String deptId = getLoginUser().getDept().getId();
        return engineService.page(risk,user.getId(),cycle,deptId,page,rows);
    }

    /**
     * 获取风险详情下载
     * @param fxid 风险ID
     * @param cycle 风险周期
     * @return 数据
     */
    @RequestMapping("detail_risk_download")
    @ResponseBody
    public void detailRiskDownload(
            HttpServletResponse response,
            String fxid,
            String cycle
    ){
        OutputStream stream = null;
        try {
            Risk risk = Engine.getRisk(fxid);
            String deptId = getLoginUser().getDept().getId();
            List<Map> datas = engineService.list(risk,cycle,deptId);
            HSSFWorkbook file = date2Xlsx(risk,datas);
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename=" + (new String(("风险详单-"+cycle+".xls").getBytes("gb2312"), "iso8859-1")));
            stream = response.getOutputStream();
            file.write(stream);
            response.flushBuffer();
        } catch (Exception e) {
            throw new UIException("风险文件获取失败！", e);
        } finally {
            try {
                if (null != stream) {
                    stream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    private HSSFWorkbook date2Xlsx(Risk risk, List<Map> datas){
        HSSFWorkbook wookBook = new HSSFWorkbook();
        HSSFSheet sheet = wookBook.createSheet("风险详单");
        try {
            HSSFFont font = wookBook.createFont();
            font.setFontHeightInPoints((short) 10); // 字体高度

            CellStyle cellStyle= wookBook.createCellStyle();
            cellStyle.setFont(font);
            //边框
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBottomBorderColor(HSSFColor.BLACK.index);
            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
            //垂直居中
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平
            //自动换行
            cellStyle.setWrapText(true);

            //设置行高
            sheet.createRow(0).setHeight((short)500);
            List<Column> columns = risk.getColumns();
            for(int i=0; i < columns.size();i++){
                Column column = columns.get(i);
                ExcelUtil.setCellValue(sheet, 0, i, column.getName(), HSSFCell.CELL_TYPE_STRING, cellStyle);
                sheet.setColumnWidth(i, 5000);
            }
            for (int i = 0; i < datas.size(); i++) {
                Map map = datas.get(i);
                //设置行高
                sheet.createRow(i+1).setHeight((short)500);
                for(int j=0; j < columns.size();j++){
                    Column column = columns.get(j);
                    ExcelUtil.setCellValue(sheet, i+1, j, map.get(column.getId()), HSSFCell.CELL_TYPE_STRING, cellStyle);
                }
            }
        } catch (Exception e) {
            LOGGER.error("生成风险详单失败：", e);
            return wookBook;
        }
        return wookBook;
    }
    /**
     * 获取风险结构
     * @param fxid 风险id
     * @return 风险结构
     */
    @RequestMapping("get_risk")
    @ResponseBody
    public Risk getRisk(
            String fxid
    ){
        return Engine.getRisk(fxid);
    }
}
